package org.jetlinks.community.mstn.web;


import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.authorization.annotation.*;
import org.jetlinks.community.auth.entity.OrganizationEntity;
import org.jetlinks.community.auth.entity.UserDetail;
import org.jetlinks.community.auth.enums.OrgType;
import org.jetlinks.community.auth.enums.RoleState;
import org.jetlinks.community.auth.enums.RoleType;
import org.jetlinks.community.auth.service.UserDetailService;
import org.jetlinks.community.mstn.entity.vo.MultiTenantCreateReqVO;
import org.jetlinks.community.mstn.entity.vo.ProjectCreateReqVO;
import org.jetlinks.community.mstn.entity.vo.ProjectDetailResVO;
import org.jetlinks.community.mstn.entity.vo.TenantListResVO;
import org.jetlinks.community.mstn.service.TenantService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.List;

@RestController
@RequestMapping("/mstn/multi/tenant")
@Authorize
@Resource(id = "multi-tenant", name = "多租户管理", group = "mstn")
@Tag(name = "多租户管理")
@AllArgsConstructor
public class MultiTenantController {

    private final TenantService tenantService;

    private final UserDetailService userDetailService;


    @PostMapping("/list")
    @QueryAction
    @Operation(summary = "用户列表")
    public Mono<PagerResult<UserDetail>> queryUserDetail(@RequestBody Mono<QueryParamEntity> query) {
        return query.doOnNext(queryParamEntity -> {
                List<Term> terms = queryParamEntity.getTerms();
                //查询出角色为租户
                Term roleTypeTerm = new Term();
                roleTypeTerm.setColumn("type");
                roleTypeTerm.setValue(RoleType.multiTenant);
                terms.add(roleTypeTerm);
            }
        ).flatMap(userDetailService::queryUserDetail);
    }

    @PostMapping
    @CreateAction
    @Operation(summary = "创建租户")
    @Transactional
    public Mono<String> create(@RequestBody MultiTenantCreateReqVO createReqVO) {
        return tenantService.saveMultiTenant(createReqVO);
    }

    @PutMapping
    @SaveAction
    @Operation(summary = "修改租户")
    @Transactional
    public Mono<String> update(@RequestBody MultiTenantCreateReqVO createReqVO) {
        return tenantService.saveMultiTenant(createReqVO);
    }


    @PostMapping("/project/list")
    @QueryAction
    @Operation(summary = "项目列表列表")
    public Mono<PagerResult<TenantListResVO>> list(@RequestBody Mono<QueryParamEntity> param) {
        return param.doOnNext( queryParamEntity -> {
            List<Term> terms = queryParamEntity.getTerms();
            //查询出机构为项目的
            Term orgTypeTerm = new Term();
            orgTypeTerm.setColumn("orgType");
            orgTypeTerm.setValue(OrgType.project);
            terms.add(orgTypeTerm);

            //查询出用户为多租户的
            Term userTypeTerm = new Term();
            userTypeTerm.setColumn("j_2.type");
            userTypeTerm.setValue(RoleType.multiTenant);
            terms.add(userTypeTerm);
        }).flatMap(tenantService::projectList);
    }

    @PostMapping("/project/{projectId}")
    @QueryAction
    @Operation(summary = "项目详情")
    public Mono<ProjectDetailResVO> createProject(@PathVariable("projectId") String projectId) {
        return tenantService.projectDetail(projectId);
    }
    @PostMapping("/project")
    @CreateAction
    @Operation(summary = "创建项目")
    @Transactional
    public Mono<String> createProject(@RequestBody ProjectCreateReqVO createReqVO) {
        return tenantService.saveProject(createReqVO);
    }

    @PutMapping("/project")
    @SaveAction
    @Operation(summary = "修改项目")
    @Transactional
    public Mono<Boolean> updateProject(@RequestBody ProjectCreateReqVO createReqVO) {
        return tenantService.updateProject(createReqVO);
    }

    @PutMapping("/project/change")
    @SaveAction
    @Operation(summary = "修改默认选中项目")
    @Transactional
    public Mono<Boolean> updateCurrentProject(@RequestBody ProjectCreateReqVO createReqVO) {
        return userDetailService.changeBindUserTenantId(createReqVO.getUserId(),createReqVO.getOrgId());
    }

    @PutMapping("/project/{id}/enabled")
    @SaveAction
    @Operation(summary = "启用租户")
    public Mono<Integer> enabled(@PathVariable String id) {
        return tenantService.updateTenantState(id ,RoleState.enabled);
    }

    @PutMapping("/project/{id}/disabled")
    @SaveAction
    @Operation(summary = "禁用租户")
    public Mono<Integer> disabled(@PathVariable String id) {
        return tenantService.updateTenantState(id ,RoleState.disabled);
    }


    @PostMapping("/{type}")
    @CreateAction
    @Operation(summary = "创建站点/分组")
    @Transactional
    public Mono<String> createOrg(
        @PathVariable   String type,
        @RequestBody OrganizationEntity organizationEntity) {
        organizationEntity.setOrgType(OrgType.valueOf(type));
        return tenantService.createOrg(type,organizationEntity);
    }

    @DeleteMapping("/{type}/{orgId}")
    @DeleteAction
    @Operation(summary = "删除站点/分组")
    @Transactional
    public Mono<Boolean> createOrg(
        @PathVariable   String type,
        @PathVariable   String orgId) {
        if ("group".equals(type)){
            return tenantService.removeGroup(orgId);
        } else {
            //不支持删除
            return Mono.error(new UnsupportedOperationException());
        }
    }


}
